package com.onepower.admin.socket;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import com.onepower.core.utils.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;


@ServerEndpoint("/websocket/{sid}/{uid}/{type}/{time}")
@Component
@Controller
public class WebSocketServer {


    private static RedisTemplate<Serializable, Object> redisTemplate;
    @Autowired
    public void setChatService(RedisTemplate<Serializable, Object> redisTemplate) {
        WebSocketServer.redisTemplate = redisTemplate;
    }


    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;

    //接收sid
    //private String sid="";
    private String uid="";
    Map<String,Object> map = new HashMap<>();
    @OnOpen
    public void open(Session session, @PathParam("sid") String sid,
                     @PathParam("uid") String uid,
                     @PathParam("type") String type,
                     @PathParam("time") String time) throws IOException {
        this.session = session;
        webSocketSet.add(this);     //加入set中
        addOnlineCount();           //在线数加1
        this.uid=uid;
        if ("play".equals(type)){
            String countdown = (String) redisTemplate.opsForValue().get("countdown"+sid);
            if (countdown != null){
                map.put("countdown",countdown);
                map.put("status","waiting");
                String message = JsonUtil.getInstance().object2JSON(map);
                sendMessage(message);
            }else {
                redisTemplate.opsForValue().set("countdown"+sid,time);
                map.put("countdown",time);
                map.put("status","waiting");
                String message = JsonUtil.getInstance().object2JSON(map);
                sendMessage(message);
            }
        }
    }

    // 关闭连接调用
    @OnClose
    public void close(Session session, @PathParam("uid") String uid) {
        for (WebSocketServer item : webSocketSet) {
            try {
                if(item.uid.equals(uid)){
                    webSocketSet.remove(item);
                }
            } catch (Exception e) {
                continue;
            }
        }
    }

    public void send(Map<String,Object> map){
        String uidTemp = map.get("uid").toString();
        for (WebSocketServer item : webSocketSet) {
            try {
                if(item.uid.equals(uidTemp+"show")){
                    item.sendMessage(JsonUtil.getInstance().object2JSON(map));
                }
            } catch (IOException e) {
                continue;
            }
        }
    }

    // 接收消息
    @OnMessage
    public void message(String message, Session session) throws IOException {
        Map<String,Object> map = JsonUtil.getInstance().json2Object(message,Map.class);
        String sidTemp = map.get("sid").toString();
        Object status = map.get("status");
        if("stop".equals(status)){
            redisTemplate.delete("countdown"+sidTemp);
            map.put("countdown","00:00");
            map.put("status","stop");
            send(map);
        }else if("start".equals(status)){
            String countdown = (String) redisTemplate.opsForValue().get("countdown"+sidTemp);
            if (countdown != null && !countdown.equals("00:00")){
                map.put("countdown",countdown);
                map.put("status","start");
                send(map);

            }else {
                map.put("countdown","01:30");
                map.put("status","start");
                redisTemplate.opsForValue().set("countdown"+sidTemp,"01:30");
                send(map);
            }
        }else if("end".equals(status)) {
            //redisTemplate.delete("countdown"+sidTemp);
            redisTemplate.opsForValue().set("countdown"+sidTemp,"00:00");
        }else if ("suspend".equals(status)){
            map.put("status","suspend");
            send(map);
        }else if ("suspend1".equals(status)){
            redisTemplate.opsForValue().set("countdown"+sidTemp,map.get("countdown"));
        }else if ("publish".equals(status)){
            map.put("status","publish");
            send(map);
        }else if ("orderIndexPublish".equals(status)){
            map.put("status","orderIndexPublish");
            send(map);
        }else if ("updateInfo".equals(status)){
            map.put("status","updateInfo");
            send(map);
        }else if ("switchSchedule".equals(status)){
            map.put("status","switchSchedule");
            send(map);
        }else if ("twoTimefinalShow".equals(status)){
            redisTemplate.opsForValue().set("finalShow"+sidTemp,map.get("boxCheck"));
            map.put("status","twoTimefinalShow");
            send(map);
        }
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

}
